package com.adui.mgt.performance.service.base.impl;

import com.adui.mgt.performance.common.ListMatch;
import com.adui.mgt.performance.entity.BaseEntity;
import com.adui.mgt.performance.service.base.IBaseService;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.function.Function;

import static com.adui.mgt.performance.common.CommonUtil.handleObjLog;

public class BaseServiceImpl<M extends BaseMapper<T>, T extends BaseEntity> extends ServiceImpl<M, T> implements IBaseService<M, T> {

	@Override
	public M getMapper() {
		return baseMapper;
	}

	@Transactional
	@Override
	public boolean save(T entity) {
		handleObjLog(entity);
		return super.save(entity);
	}

	@Transactional
	@Override
	public boolean updateById(T entity) {
		handleObjLog(entity);
		return super.updateById(entity);
	}

	/**
	 * 合并（根据ID与旧List比较，将新List更新到数据库中）
	 * 
	 * @return int[]<br/>
	 *         int[0] 删除的行数<br/>
	 *         int[1] 新增的行数<br/>
	 *         int[2] 修改的行数<br/>
	 */
	@Transactional
	@Override
	public int[] replace(List<T> oldList, List<T> newList) {
		return new ListMatch<T, T>() {

			@Override
			protected Comparable<?>[] getKeys1(T item1) {
				return new Comparable<?>[] { item1.getId() };
			}

			@Override
			protected Comparable<?>[] getKeys2(T item2) {
				return new Comparable<?>[] { item2.getId() };
			}

			@Override
			protected void onOnlyItem1(T item1) {
				removeById(item1.getId());
			}

			@Override
			protected void onOnlyItem2(T item2) {
				save(item2);
			}

			@Override
			protected void onMatched(T item1, T item2) {
				updateById(item2);
			}

		}.match(oldList, newList);
	}

	/** 合并（查询旧List，将新List更新到数据库中） */
	@Transactional
	@Override
	public int[] replace(Wrapper<T> queryWrapper, List<T> newList) {
		return replace(list(queryWrapper), newList);
	}

	/** 合并（查询旧List，将新List更新到数据库中） */
	@Transactional
	@Override
	public int[] replace(SFunction<T, ?> column, Object val, List<T> newList) {
		return replace(Wrappers.<T>lambdaQuery().eq(column, val), newList);
	}

	/** 合并（查询旧List，将新List更新到数据库中） */
	@Transactional
	@Override
	public int[] replace(SFunction<T, ?> column1, Object val1, SFunction<T, ?> column2, Object val2, List<T> newList) {
		return replace(Wrappers.<T>lambdaQuery().eq(column1, val1).eq(column2, val2), newList);
	}

	public <A> A getValueById(Function<T, A> target, String id) {
		T entity = this.getById(id);
		if (entity == null) {
			return null;
		}
		return target.apply(entity);
	}

	public <A> A getValueBy(Function<T, A> target, SFunction<T, ?> column, Object val) {
		T entity = this.getOne(Wrappers.<T>lambdaQuery()
				.eq(column, val), false);
		if (entity == null) {
			return null;
		}
		return target.apply(entity);
	}

	public <A> A getValueBy(Function<T, A> target, SFunction<T, ?> column1, Object val1, SFunction<T, ?> column2, Object val2) {
		T entity = this.getOne(Wrappers.<T>lambdaQuery()
				.eq(column1, val1)
				.eq(column2, val2), false);
		if (entity == null) {
			return null;
		}
		return target.apply(entity);
	}

}
